package com.example.musicserver.controller;

import com.example.musicserver.constant.Constant;
import com.example.musicserver.constant.FileType;
import com.example.musicserver.model.MusicInfo;
import com.example.musicserver.model.Result;
import com.example.musicserver.model.UserInfo;
import com.example.musicserver.service.LoveMusicService;
import com.example.musicserver.service.MusicInfoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.tika.Tika;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/music")
public class MusicController {
    @Autowired
    private MusicInfoService musicInfoService;

    @Autowired
    private LoveMusicService loveMusicService;

    @RequestMapping("/getlist")
    public Result<Object[]> getList(String musicName) {
        List<MusicInfo> list;
        Object[] arr;
        if (musicName == null || musicName.isEmpty()) {
            list = musicInfoService.getList();
        }else {
            list = musicInfoService.getList(musicName);
        }
        arr = list.toArray();
        return Result.success(arr);
    }

    @RequestMapping("/upload")
    public Result<Boolean> upload(@RequestPart("filename") MultipartFile file, String singer, HttpSession session) {
        String fileName = file.getOriginalFilename();
        if (fileName == null || fileName.isEmpty()) {
            return Result.fail(406,"您上传的文件名非法，请确认后重试",false);
        }
        //判断上传的文件是否为音乐类型
        Tika tika = new Tika();
        File tFile = new File(fileName);
        try {
            FileUtils.copyInputStreamToFile(file.getInputStream(),tFile);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        try {
            String fileType = tika.detect(tFile);
            if (!fileType.equals(FileType.FILE_TYPE_MP3) &&
                    !fileType.equals(FileType.FILE_TYPE_FLAC)) {
                return Result.fail(406,"您上传的文件类型不正确，请确认后重试",false);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        tFile.delete();
        String localFileName = Constant.PATH + fileName;
        System.out.println("localFileName: " + localFileName);
        File localFile = new File(localFileName);
        try {
            //查询要上传的音乐是否已经存在
            MusicInfo musicInfo = musicInfoService.queryMusicByTitle(fileName);
            if (musicInfo != null) {
                return Result.fail(406,"您上传的文件已存在",false);
            }
            //将文件保存到服务器本地
            file.transferTo(localFile);
            //将音乐信息保存到数据库
            int index = fileName.lastIndexOf(".");
            String url = "/music/get?path=" + fileName;
            UserInfo userInfo = (UserInfo) session.getAttribute(Constant.USERINFO_SESSION_KEY);
            int userId = userInfo.getId();
            musicInfoService.addMusic(fileName,singer,url,userId);
            return Result.success(true);
        } catch (IOException e) {
            e.printStackTrace();
            return Result.fail(500,"音乐上传失败，请联系管理员",false);
        }
    }

    @RequestMapping("/get")
    public ResponseEntity<byte[]> get(String path) {
        System.out.println(Constant.PATH + path);
        File file = new File(Constant.PATH + path);
        byte[] arr;
        try {
            arr = Files.readAllBytes(file.toPath());
            return ResponseEntity.ok(arr);
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.badRequest().build();
        }
    }

    @RequestMapping("/delete")
    public Result<Boolean> deleteMusic(Integer id) {
        if (id == null || id < 0) {
            log.error("删除音乐前端传来的id：" + id);
            return Result.fail(500,"内部出现错误，请连续管理员",false);
        }
        MusicInfo musicInfo = musicInfoService.findMusicByMId(id);
        Integer ret;
        //删除music库中的音乐
        ret = musicInfoService.deleteMusicByMId(id);
        if (ret != 1) {
            return Result.fail(500,"删除音乐失败，请联系管理员",false);
        }
        //删除lovemusic库中的该音乐
        ret = loveMusicService.deleteLoveMusic(null,id);
        //删除本地音乐
        String url = musicInfo.getUrl();
        int index = url.lastIndexOf("=");
        String filePath = Constant.PATH + url.substring(index + 1);
        File file = new File(filePath);
        if (file.delete()) {
            return Result.success(true);
        }else {
            return Result.fail(500,"服务器中的音乐删除失败",false);
        }
    }

    @RequestMapping("/deleteSel")
    public Result<Boolean> deleteSel(@RequestParam("id[]") List<Integer> id) {
        log.info("id数组：" + id);
        if (id == null || id.size() <= 0) {
            log.error("前端传来的id数组有问题");
            return Result.fail(500,"内部出现错误，请联系管理员",false);
        }
        MusicInfo musicInfo;
        Integer ret;
        for (Integer i : id) {
            musicInfo = musicInfoService.findMusicByMId(i);
            //删除music库中的音乐
            ret = musicInfoService.deleteMusicByMId(i);
            if (ret != 1) {
                return Result.fail(500,"删除音乐失败，请联系管理员",false);
            }
            //删除lovemusic库中的该音乐
            ret = loveMusicService.deleteLoveMusic(null,i);
            //删除本地音乐
            String url = musicInfo.getUrl();
            int index = url.lastIndexOf("=");
            String filePath = Constant.PATH + url.substring(index + 1);
            File file = new File(filePath);
            if (!file.delete()) {
                return Result.fail(500,"服务器中的音乐删除失败",false);
            }
        }
        return Result.success(true);
    }
}
